﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Serialization;
using System.Xml.Schema;
using System.Xml;
using Microsoft.SharePoint;
using System.Xml.Linq;
using System.Runtime.Serialization;
using System.IO;


namespace BIMP
{

    [DataContract]
    [KnownType(typeof(SPSchedule))]
    [KnownType(typeof(SPMinuteSchedule))]
    [KnownType(typeof(SPHourlySchedule))]
    [KnownType(typeof(SPDailySchedule))]
    [KnownType(typeof(SPWeeklySchedule))]
    [KnownType(typeof(SPMonthlySchedule))]
    [KnownType(typeof(SPMonthlyByDaySchedule))]
    public class RmdConfiguration// : IXmlSerializable
    {
        public RmdConfiguration()
        {
            this.Id = Guid.NewGuid();
            //this.Type = RmdType.Item;
            this.Schedule = null;
            this.XslTransform = @"<?xml version=""1.0""?>
<xsl:stylesheet version=""1.0"" xmlns:xsl=""http://www.w3.org/1999/XSL/Transform"">

<xsl:template match=""/"">
<Email>
<From />
<To />
<Subject />
<Body IsHtml=""true"">
<xsl:apply-templates />
</Body>
</Email>
</xsl:template>

<xsl:template match=""root"">
<xsl:for-each select=""./node()"">
<xsl:copy-of select="".""/>
</xsl:for-each>
</xsl:template>

</xsl:stylesheet>
";
            this.AuthorID = string.Empty;
        }

        [DataMember]
        public Guid Id
        {
            get;
            set;
        }

        /// <summary>
        /// The name used for the unique identification of the configuration.
        /// </summary>
        [DataMember]
        public string DisplayName
        {
            get;
            set;
        }

        [DataMember]
        public SPSchedule Schedule { get; set; }

        /// <summary>
        /// The XSL that is used to transform the items returned in the query to an HTML body
        /// for the email.
        /// </summary>
        [DataMember]
        public string XslTransform
        {
            get;
            set;
        }
        [DataMember]
        public string AuthorID
        {
            get;
            set;
        }

        [DataMember]
        public Guid SiteId { get; set; }
        [DataMember]
        public Guid WebId { get; set; }
        [DataMember]
        public Guid ListId { get; set; }

        [DataMember]
        public string DataSourceCFG {get;set;}
        /*
        #region IXmlSerializable Members

        public XmlSchema GetSchema()
        {
            return null;
        }



        public void ReadXml(XmlReader reader)
        {
            string outerXml = reader.ReadOuterXml();

            try
            {

                bool isEmpty = reader.IsEmptyElement;
                reader.Read();
                if (isEmpty)
                {
                    return;
                }

                reader.MoveToContent();

                while (!(reader.Name.Equals("RmdConfiguration") && reader.NodeType == XmlNodeType.EndElement))
                {
                    string configElement = reader.Name;
                    isEmpty = reader.IsEmptyElement;

                    reader.ReadStartElement();

                    if (isEmpty)
                        continue;

                    switch (configElement)
                    {
                        case "Id":
                            this.Id = GenericSerializer.Deserialize<Guid>(reader);
                            break;
                        case "SiteId":
                            this.SiteId = GenericSerializer.Deserialize<Guid>(reader);
                            break;
                        case "WebId":
                            this.WebId = GenericSerializer.Deserialize<Guid>(reader);
                            break;
                        case "ListId":
                            this.ListId = GenericSerializer.Deserialize<Guid>(reader);
                            break;
                        case "DisplayName":
                            this.DisplayName = GenericSerializer.Deserialize<string>(reader);
                            break;
                        case "Schedule":
                            this.Schedule = GenericSerializer.Deserialize<SPSchedule>(reader
                                , new Type[] {
                                typeof(SPSchedule),
                                typeof(SPMinuteSchedule),
                                typeof(SPHourlySchedule),
                                typeof(SPDailySchedule),
                                typeof(SPWeeklySchedule),
                                typeof(SPMonthlySchedule),
                                typeof(SPMonthlyByDaySchedule),
                                typeof(SPYearlySchedule)
                            });
                            break;
                        case "XslTransform":
                            this.XslTransform = GenericSerializer.Deserialize<string>(reader);
                            break;
                        case "AuthorID":
                            this.AuthorID = GenericSerializer.Deserialize<string>(reader);
                            break;
                        default:
                            while (!reader.Name.Equals(configElement) && reader.NodeType == XmlNodeType.EndElement)
                                reader.Read();
                            break;
                    }
                    reader.ReadEndElement();
                    reader.MoveToContent();
                }

                //Read Closing Element
                reader.ReadEndElement();
            }
            catch (Exception exc)
            {
                XElement xe = XElement.Parse(outerXml);
                this.Id = new Guid(xe.Element("Id").Value);
                this.DisplayName = xe.Element("DisplayName").Value;
                this.SiteId = new Guid(xe.Element("SiteId").Value);
                this.WebId = new Guid(xe.Element("WebId").Value);
                this.ListId = new Guid(xe.Element("ListId").Value);
            }
        }

        public void WriteXml(XmlWriter writer)
        {
            writer.WriteStartElement("Id");
            GenericSerializer.Serialize<Guid>(this.Id, writer);
            writer.WriteEndElement();
            
            writer.WriteStartElement("SiteId");
            GenericSerializer.Serialize<Guid>(this.SiteId, writer);
            writer.WriteEndElement();
            
            writer.WriteStartElement("WebId");
            GenericSerializer.Serialize<Guid>(this.WebId, writer);
            writer.WriteEndElement();
            
            writer.WriteStartElement("ListId");
            GenericSerializer.Serialize<Guid>(this.ListId, writer);
            writer.WriteEndElement();
            
            writer.WriteStartElement("DisplayName");
            GenericSerializer.Serialize<string>(this.DisplayName, writer);
            writer.WriteEndElement();
            
            writer.WriteStartElement("Schedule");
            GenericSerializer.Serialize<SPSchedule>(this.Schedule, writer, new Type[] {
                typeof(SPSchedule),
                typeof(SPMinuteSchedule),
                typeof(SPHourlySchedule),
                typeof(SPDailySchedule),
                typeof(SPWeeklySchedule),
                typeof(SPMonthlySchedule),
                typeof(SPMonthlyByDaySchedule),
                typeof(SPYearlySchedule)
            });
            writer.WriteEndElement();
  
            writer.WriteStartElement("XslTransform");
            GenericSerializer.Serialize<string>(this.XslTransform, writer);
            writer.WriteEndElement();

            writer.WriteStartElement("AuthorID");
            GenericSerializer.Serialize<string>(this.AuthorID, writer);
            writer.WriteEndElement();
        }

        #endregion

        /// <summary>
        /// Deserializes the string and returns the associated object.
        /// </summary>
        /// <param name="strConfiguration"></param>
        /// <returns></returns>
        public static List<RmdConfiguration> ReadConfigurations(string strConfiguration)
        {
            return GenericSerializer.Deserialize<List<RmdConfiguration>>(strConfiguration);
        }

        /// <summary>
        /// Serializes the object into a string so it can be used for storage.
        /// </summary>
        /// <param name="config"></param>
        /// <returns></returns>
        public static string WriteConfigurations(List<RmdConfiguration> config)
        {
            return GenericSerializer.Serialize<List<RmdConfiguration>>(config);
        }
        */

        /// <summary>
        /// Deserializes the string and returns the associated object.
        /// </summary>
        /// <param name="strConfiguration"></param>
        /// <returns></returns>
        public static List<RmdConfiguration> ReadConfigurations(string strConfiguration)
        {
            StringBuilder sb = new StringBuilder();
            sb.Append(strConfiguration);

            DataContractSerializer dcs = new DataContractSerializer(typeof(List<RmdConfiguration>), new List<Type>() {
                typeof(RmdConfiguration),
                typeof(SPSchedule),
                typeof(SPMinuteSchedule),
                typeof(SPHourlySchedule),
                typeof(SPDailySchedule),
                typeof(SPWeeklySchedule),
                typeof(SPMonthlySchedule),
                typeof(SPMonthlyByDaySchedule)
            });

            var reader = XmlReader.Create(new StringReader(strConfiguration));
            List<RmdConfiguration> config = (List<RmdConfiguration>)dcs.ReadObject(reader, true);
            reader.Close();

            return config;
        }

        /// <summary>
        /// Serializes the object into a string so it can be used for storage.
        /// </summary>
        /// <param name="config"></param>
        /// <returns></returns>
        public static string WriteConfigurations(List<RmdConfiguration> config)
        {
            DataContractSerializer dcs = new DataContractSerializer(typeof(List<RmdConfiguration>), new List<Type>() {
                typeof(RmdConfiguration),
                typeof(SPSchedule),
                typeof(SPMinuteSchedule),
                typeof(SPHourlySchedule),
                typeof(SPDailySchedule),
                typeof(SPWeeklySchedule),
                typeof(SPMonthlySchedule),
                typeof(SPMonthlyByDaySchedule)
            });

            StringBuilder sb = new StringBuilder();
            XmlWriter xmlWriter = XmlWriter.Create(sb);
            dcs.WriteObject(xmlWriter, config);
            xmlWriter.Flush();
            string ret = sb.ToString();
            xmlWriter.Close();

            return ret;
        }
    }
}
